﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace CloudStorageLight.Core.Tests
{
    [TestClass]
    public class FullTextServiceTest
    {
        [TestInitialize()]
        public void MyTestInitialize() 
        {
            using (var svc = CreateFullTextService())
            {
                svc.Init();
            }        
        }


        private TestContext testContextInstance;

        /// <summary>
        ///現在のテストの実行についての情報および機能を
        ///提供するテスト コンテキストを取得または設定します。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        private FullTextServiceBase CreateFullTextService()
        {
            return new FullTextServiceBase(ConfigurationManager.AppSettings["blobService.containerName"] + "unitcatalog", ConfigurationManager.AppSettings["blobService.connectionString"]);
        }


        [TestMethod]
        public void コンストラクタ()
        {
            using (var svc = CreateFullTextService())
            {
            }
        }
        [TestMethod]
        public void インデックス追加()
        {
            var sw = Stopwatch.StartNew();

            using (var svc = CreateFullTextService())
            {
                for (int i = 0; i < 100; i++)
                {
                    svc.Entry("id" + i.ToString(), "タイトル" + i.ToString(), "コンテンツ" + i.ToString()).Wait();
                    TestContext.WriteLine(sw.Elapsed.ToString());
                }

                svc.Commit();
                Assert.AreEqual(100, svc.Search("タイトル", 1000).Count);
                TestContext.WriteLine(sw.Elapsed.ToString());
            }
            TestContext.WriteLine(sw.Elapsed.ToString());
        }

        [TestMethod]
        public void インデックス追加_マルチスレッド()
        {
            var sw = Stopwatch.StartNew();

            using (var svc = CreateFullTextService())
            {
                System.Linq.Enumerable.Range(0,100).AsParallel().ForAll(i => {
                    svc.Entry("id" + i.ToString(), "タイトル" + i.ToString(), "コンテンツ" + i.ToString()).Wait();
                    TestContext.WriteLine(sw.Elapsed.ToString());
                               
                });

                svc.Commit();
                Assert.AreEqual(100, svc.Search("タイトル", 1000).Count);
                TestContext.WriteLine(sw.Elapsed.ToString());
            }
            TestContext.WriteLine(sw.Elapsed.ToString());
        }

        [TestMethod]
        public void インデックス削除()
        {
            using (var svc = CreateFullTextService())
            {
                for (int i = 0; i < 100; i++)
                {
                    svc.Entry("id" + i.ToString(), "タイトル" + i.ToString(), "コンテンツ" + i.ToString()).Wait();
                }

                svc.DeleteEntry("id0").Wait();
                svc.Commit();
                svc.RenewSearcherIndex();
                Assert.AreEqual(99, svc.Search("コンテンツ", 1000).Count);
            }
        }


        [TestMethod]
        public void インデックス削除_マルチスレッド()
        {
            using (var svc = CreateFullTextService())
            {

                for (int i = 0; i < 100; i++)
                {
                    svc.Entry("id" + i.ToString(), "タイトル" + i.ToString(), "コンテンツ" + i.ToString()).Wait();
                }

                System.Linq.Enumerable.Range(0, 99).AsParallel().ForAll(i =>
                {
                    svc.DeleteEntry("id" + i.ToString()).Wait();

                });

                svc.Commit();
                Assert.AreEqual(1, svc.Search("コンテンツ", 1000).Count);
            }
        }

        [TestMethod]
        public void インデックス重複登録()
        {
            using (var svc = CreateFullTextService())
            {
                for (int i = 0; i < 5; i++)
                {
                    svc.Entry("/テスト/タイトル1.txt", "タイトル1.txt","コンテンツ" + i.ToString()).Wait();
                }
                svc.Commit();
                svc.RenewSearcherIndex();
                Assert.AreEqual(1, svc.Search("タイトル", 1000).Count);
            }
        }

        [TestMethod]
        public void インデックスID取得()
        {
            using (var svc = CreateFullTextService())
            {
                var id = "/単体テスト用/サブディレクトリ 2/テキスト/xxxxxxxxxxx.txt";
                svc.Entry(id, "", "").Wait();
                svc.Commit();
                Assert.IsNotNull(svc.SearchById(id));
            }
        }

        [TestMethod]
        public void インデックス追加検索_マルチスレッド()
        {
            var sw = Stopwatch.StartNew();

            using (var svc = CreateFullTextService())
            {
                System.Linq.Enumerable.Range(0, 100).AsParallel().ForAll(i =>
                {
                    if ((i % 2) == 0)
                    {
                        svc.Entry("id" + i.ToString(), "検索データ" + i.ToString(), "コンテンツ" + i.ToString()).Wait();
                        TestContext.WriteLine(sw.Elapsed.ToString());
                    }
                    else
                    {
                        var items = svc.Search("タイトル");
                    }

                });

                svc.Commit();
                svc.Optimize();
                svc.RenewSearcherIndex();
                Assert.AreEqual(50, svc.Search("検索データ", 1000).Count);
                TestContext.WriteLine(sw.Elapsed.ToString());
            }
            TestContext.WriteLine(sw.Elapsed.ToString());
        }
    }
}
